﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

using Helper;
using Highlearner_API;

using Logging;


namespace Highlearner
{
	enum EInstituteName
	{
		TAU = 0,
		HUJI = 1
	}

	enum EState
	{
		Disconnected,
		Connected,
		Downloading,
	}

	public partial class FormMain : Form
	{
		private delegate void SetStatusDelegate(EState a_eState);

		private Boolean DEBUG_COURSE = false;

		public String[] InstituteNames = new String[] 
		{
			"אוניברסיטת תל אביב",
			"האוניברסיטה העברית בירושלים"
		};

		private const string COURSES_FILE_PATH_END = "SavedCourses.dat";

		private String m_sCoursesFilePath = "";
		/// <summary>
		/// States if the courses list was loaded from a file, not from the Highlearn 
		/// system. Used to not load the courses GUI list again (closes the tree nodes).
		/// </summary>
		private bool m_bLoadedFromFileFlag = false;

		private Miner_Highlearn.frm_Log FormLog;
		private Executer hl;
		private Course m_oCurrentCourse = null;
		private FolderItem m_oCurrentFolder = null;

		private CListViewAnimator m_oAnimator;

		private List<Course> m_oCurrentDownloadedCourses = new List<Course>();

		private int m_iDownloadFilesCount = 0;

		// States wether the tree view is populating. Good for knowing when to ignore certain events (like AfterCheck)
		private bool m_bTreeViewPopulating = false;

		private static string m_sConfigurationDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Highlearner\\";
		private string m_sConfigurationFilename = m_sConfigurationDirectory + "UserSettings.dat";
		private string m_sDownloadsPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\HighlearnerDownloads";


		public FormMain()
		{
			InitializeComponent();

			FormLog = new Miner_Highlearn.frm_Log();
			FormLog.Show();
			//edt_Log = FormLog.edt_Log;

			m_oAnimator = new CListViewAnimator(listViewCourses);

			for (int l_iInstitute = 0; l_iInstitute < InstituteNames.Length; l_iInstitute++)
			{
				comboBoxInstitute.Items.Add(InstituteNames[l_iInstitute]);
			}

			CLogger.StartLogging(m_sConfigurationDirectory + "Log.csv");
		}

		public void Initialize()
		{
			hl = new Executer();

			// Set the corresponding core for the current university
			switch (((EInstituteName)comboBoxInstitute.SelectedIndex))
			{
				case EInstituteName.TAU:
					hl.Core = (Miner_Highlearn.API_Highlearn)new Miner_Highlearn.API_HL_TAU();
					break;
				case EInstituteName.HUJI:
					hl.Core = (Miner_Highlearn.API_Highlearn)new Miner_Highlearn.API_HL_HUJI();
					break;
/*				case TMy_University.BIU:
					hl.core = (API_Highlearn)new API_HL_BIU();
					break;
				case TMy_University.BGU:
					hl.core = (API_Highlearn)new API_HL_BGU();
					break;
				case TMy_University.Haifa:
					hl.core = (API_Highlearn)new API_HL_Haifa();
					break;
				case TMy_University.Colman:
					hl.core = (API_Highlearn)new API_HL_Colman();
					break;
				case TMy_University.HIT:
					hl.core = (API_Highlearn)new API_HL_HIT();
					break;
				case TMy_University.Sapir:
					hl.core = (API_Highlearn)new API_HL_Sapir();
					break;
				case TMy_University.CET:
					hl.core = (API_Highlearn)new API_HL_CET();
					break;
				case TMy_University.Afeka:
					hl.core = (API_Highlearn)new API_HL_Afeka();
					break;
				case TMy_University.SCE:
					hl.core = (API_Highlearn)new API_HL_SCE();
					break;*/
			}
			hl.SavePath = m_sDownloadsPath;

			hl.OnConnected += new SimpleDelegate(ExecuterConnected);
			hl.OnDisconnected += new SimpleDelegate(ExecuterDisconnected);
			hl.OnCoursesLoadedEvent += new SimpleDelegate(CoursesLoaded); 
			hl.OnCourseInformationUpdated +=new CourseUpdatedDelegate(CourseInformationUpdated);
			hl.OnCourseInformationRequest += new CourseUpdatedDelegate(CourseInformationRequest);
			hl.OnFileDownloadStarted += new FileDownloadDelegate(FileDownloadStarted);
			hl.OnFileDownloadEndedSuccessfully += new FileDownloadDelegate(FileDownloadEndedSuccessfully);
			hl.OnFileDownloadFailed += new FileDownloadDelegate(FileDownloadFailed);
			hl.OnDownloadStarted += new DownloadStarted(DownloadStarted);
			hl.OnDownloadEnded += new DownloadEnded(DownloadEnded);

			hl.Core.logger = new Logger();
			hl.Core.logger.edt_Log = FormLog.edt_Log;
			hl.Core.logger.frm_Parent = this;
			hl.Core.logger.file_path = m_sConfigurationDirectory + "Log.txt";

			//			hl.prg_Courses				= prg_Courses;
			//			hl.edt_Progress_Course		= edt_Progress_Course;

			//			hl.core.prg_File			= prg_File;
			//			hl.core.edt_Progress_File	= edt_Progress_File;

			//edt_Log_Initial_Height = edt_Log.Height;
			//edt_Verbose_Level_ValueChanged(null, null);

			if (File.Exists(hl.Core.logger.file_path))
			{
				File.Delete(hl.Core.logger.file_path);
			}
		}

		private void UpdateStatus(String a_sMessage)
		{
			toolStripStatusLabel.Text = a_sMessage;
		}

		#region Executer Events

		void ExecuterConnected()
		{
			this.Invoke(new SetStatusDelegate(SetGUIState), EState.Connected);
		}

		void ExecuterDisconnected()
		{
			this.Invoke(new SetStatusDelegate(SetGUIState), EState.Disconnected);
		}

		void DownloadStarted(Course a_oCourse, int a_iNumberOfItems)
		{
			// Thread Safe Updating
			this.Invoke(new DownloadStarted(DownloadStartedSafe), a_oCourse, a_iNumberOfItems);
		}

		void DownloadStartedSafe(Course a_oCourse, int a_iNumberOfItems)
		{
			m_oCurrentDownloadedCourses.Add(a_oCourse);

			m_iDownloadFilesCount = a_iNumberOfItems;
			toolStripProgressBar.Maximum = a_iNumberOfItems;
		}

		void DownloadEnded(Course a_oCourse)
		{
			// Thread Safe Updating
			this.Invoke(new DownloadEnded(DownloadEndedSafe), a_oCourse);
		}

		void DownloadEndedSafe(Course a_oCourse)
		{
			buttonStartDownloading.Enabled = true;
			toolStripProgressBar.Enabled = false;// Value = 0;
			toolStripStatusLabelCourseName.Text = "";

			UpdateStatus("ההורדה הסתיימה");

			m_oCurrentDownloadedCourses.Remove(a_oCourse);

			if (m_oCurrentDownloadedCourses.Count == 0)
			{
				SetGUIState(EState.Connected);
				System.Diagnostics.Process.Start(hl.Core.SavePath);
			}
		}

		void FileDownloadFailed(Course a_oCourse, FolderItem a_oFolder, FileItem a_oFile)
		{
			hl.Core.logger.WriteLn("File " + a_oFolder.Name + "\\" + a_oFile.Name + " failed downloading");
		}
	
		void FileDownloadEndedSuccessfully(Course a_oCourse, FolderItem a_oFolder, FileItem a_oFile)
		{
			// Thread Safe Updating
			this.Invoke(new FileDownloadDelegate(FileDownloadEndedSuccessfullySafe), a_oCourse, a_oFolder, a_oFile);
		}

		void FileDownloadEndedSuccessfullySafe(Course a_oCourse, FolderItem a_oFolder, FileItem a_oFile)
		{
			toolStripProgressBar.ProgressBar.Value++;
		}

		void FileDownloadStarted(Course a_oCourse, FolderItem a_oFolder, FileItem a_oFile)
		{
			// Thread Safe Updating
			this.Invoke(new FileDownloadDelegate(FileDownloadStartedSafe), a_oCourse, a_oFolder, a_oFile);
		}

		private void FileDownloadStartedSafe(Course a_oCourse, FolderItem a_oFolder, FileItem a_oFile)
		{
			toolStripStatusLabelCourseName.Text = a_oCourse.Name + "    - ";

			toolStripStatusLabel.Text = "מוריד את: " + a_oFile.Name;
		}

		private void CoursesLoaded()
		{
			// Thread Safe Updating
			this.Invoke(new SimpleDelegate(CoursesLoadedSafe));
		}

		private void CoursesLoadedSafe()
		{
			ListViewItem l_oItem;
			listViewCourses.Items.Clear();
			foreach (Course l_oCourse in hl.DataCenter.Courses.Values)
			{
				l_oItem = listViewCourses.Items.Add(l_oCourse.ToString());
				l_oItem.Name = l_oCourse.ToString();
				l_oItem.Checked = l_oCourse.Download;
				l_oItem.ImageIndex = (int)l_oCourse.DataRetrieved;
			}

			listViewCourses.Items[0].Selected = true;

			edt_Verbose_Level.Enabled = buttonAbort.Enabled;
		}

		private void CourseInformationUpdated(String a_sCourseName)
		{
			this.Invoke(new CourseUpdatedDelegate(CourseInformationUpdatedSafe), a_sCourseName);
		}

		private void CourseInformationUpdatedSafe(String a_sCourseName)
		{
			m_oAnimator.RemoveItem(a_sCourseName);

			CoursesSave();

			RefreshCourseDetails();
		}

		private void CourseInformationRequest(string a_sCourseName)
		{
			this.Invoke(new CourseUpdatedDelegate(CourseInformationRequestSafe), a_sCourseName);
		}

		private void CourseInformationRequestSafe(String a_sCourseName)
		{
			m_oAnimator.AddItem(listViewCourses.Items.Find(a_sCourseName, false)[0], a_sCourseName);
		}


		#endregion

		#region GUI - Datacenter Update methods
		private void UpdateTreeNode(TreeNode a_oNode, FolderItem a_oFolder)
		{
			// Bad encapsulation alert!
			// The tree nodes are created in 2 different places - Here and in the RefreshCourseDetails method.

			TreeNode l_oNode;
			
			a_oNode.Checked = a_oFolder.Download;

			foreach (FolderItem l_oFolder in a_oFolder.Folders.Values)
			{
				l_oNode = new TreeNode(l_oFolder.Name);
				l_oNode.Name = l_oFolder.Name;

				a_oNode.Nodes.Add(l_oNode);
				UpdateTreeNode(l_oNode, l_oFolder);
			}
		}

		/// <summary>
		/// Refreshes the GUI according to the new selected course.
		/// </summary>
		private void RefreshCourseDetails()
		{
			TreeNode l_oNode;

			if (listViewCourses.SelectedItems.Count == 0)
			{
				hl.Core.logger.WriteLn("RefreshCourseDetails Ignoring Request (no item selected)");
				return;
			}

			// Don't reupdate the courses list, it is already loaded.
			if (m_bLoadedFromFileFlag)
			{
				m_bLoadedFromFileFlag = false;
				return;
			}

			treeViewFolders.Nodes.Clear();
			checkedListBoxFiles.Items.Clear();

			m_oCurrentCourse = hl.DataCenter.Courses[listViewCourses.SelectedItems[0].Text];

			if (listViewCourses.SelectedItems.Count > 0)
			{
				m_bTreeViewPopulating = true;
				foreach (FolderItem l_oFolder in m_oCurrentCourse.Data.Folders.Values)
				{
					// Bad encapsulation alert!
					// The tree nodes are created in 2 different places - Here and in the UpdateTreeNode method.
					l_oNode = treeViewFolders.Nodes.Add(l_oFolder.Name);
					l_oNode.Name = l_oFolder.Name;
					UpdateTreeNode(l_oNode, l_oFolder);
				}
				m_bTreeViewPopulating = false;

				foreach (ListViewItem l_oItem in listViewCourses.Items)
				{
					if (!(hl.DataCenter.Courses[l_oItem.Text].DataRetrieved == ERetrievedState.NotRetrieved))
					{
						l_oItem.Font = new Font(l_oItem.Font, FontStyle.Bold);
						l_oItem.ImageIndex = (int)hl.DataCenter.Courses[l_oItem.Text].DataRetrieved;
					}
				}
			}
		}

		private void RefreshFilesDetails()
		{
			int l_iFileIndex;

			if (treeViewFolders.SelectedNode != null)
			{
				m_oCurrentFolder = m_oCurrentCourse.GetFolderAt(treeViewFolders.SelectedNode.FullPath);

				checkedListBoxFiles.Items.Clear();

				foreach (FileItem l_oFile in m_oCurrentFolder.Files.Values)
				{
					l_iFileIndex = checkedListBoxFiles.Items.Add(l_oFile.ToString());
					checkedListBoxFiles.SetItemChecked(l_iFileIndex, l_oFile.Download);
				}
			}
		}

		private void RefreshFoldersCheckedState()
		{
			foreach (FolderItem l_oFolder in m_oCurrentCourse.Data.Folders.Values)
			{
//				treeViewFolders.Nodes.IndexOfKey(l_oFolder.Name);
				RefreshFoldersCheckedState(l_oFolder, treeViewFolders.Nodes[l_oFolder.Name]);
			}
		}

		private void RefreshFoldersCheckedState(FolderItem a_oFolder, TreeNode a_oNode)
		{
			TreeNode[] l_oNode;

			a_oNode.Checked = a_oFolder.Download;

			foreach (FolderItem l_oFolder in a_oFolder.Folders.Values)
			{
				l_oNode = a_oNode.Nodes.Find(l_oFolder.Name, false);
				RefreshFoldersCheckedState(l_oFolder, l_oNode[0]);
			}
		}
		#endregion


		private void ValidateConfigurationDirectory()
		{
			if (!Directory.Exists(m_sConfigurationDirectory))
			{
				Directory.CreateDirectory(m_sConfigurationDirectory);
			}
		}

		public void Config_Save_UI()
		{
			if (!checkBoxRemember.Checked)
			{
				if (File.Exists(m_sConfigurationFilename))
				{
					File.Delete(m_sConfigurationFilename);
				}
			}
			else
			{
				Config_Save(m_sConfigurationFilename);
			}
		}
		public void Config_Save(string filename)
		{	
			Hashtable obj = new Hashtable();
			obj["username"] = textBoxUsername.Text;
			obj["password"] = textBoxPassword.Text;
			obj["institute"] = comboBoxInstitute.SelectedIndex;
			obj["SaveMyCourses"] = checkBoxSaveMyCourses.Checked.ToString();
			obj["Institute"] = comboBoxInstitute.SelectedIndex;
			obj["DownloadsPath"] = m_sDownloadsPath;

			ValidateConfigurationDirectory();

			FileStream fs = File.Open(filename, FileMode.Create);
			BinaryFormatter b = new BinaryFormatter();
			b.Serialize(fs, obj);
			fs.Close();
		}
		public void Config_Load()
		{
			Hashtable obj = null;

			if (!File.Exists(m_sConfigurationFilename))
			{
				return;
			}

			checkBoxRemember.Checked = true;

			// Open the file containing the data that you want to deserialize.
			FileStream fs = new FileStream(m_sConfigurationFilename, FileMode.Open);
			try
			{
				BinaryFormatter b = new BinaryFormatter();
				obj = (Hashtable)b.Deserialize(fs);

				textBoxUsername.Text = (string)obj["username"];
				textBoxPassword.Text = (string)obj["password"];
				comboBoxInstitute.SelectedIndex = (int)obj["institute"];
				checkBoxSaveMyCourses.Checked = bool.Parse((string)obj["SaveMyCourses"]);
				comboBoxInstitute.SelectedIndex = (int)obj["Institute"];
				UpdateDownloadsPath((string)obj["DownloadsPath"]);
				
			}
			catch (SerializationException e)
			{
				hl.Core.logger.WriteLn("Failed to load user configurations. Reason: " + e.Message);
				throw;
			}
			finally
			{
				fs.Close();
			}

			SetGUIState(EState.Disconnected);
		}

		/// <summary>
		/// Saves the current courses data to file
		/// </summary>
		public void CoursesSave()
		{
			CoursesSave(false);
		}

		public void CoursesSave(bool a_bOverrideCheckbox)
		{
			if ((a_bOverrideCheckbox) || (checkBoxSaveMyCourses.Checked))
			{
				try
				{
					ValidateConfigurationDirectory();

					Stream l_oStream = File.Open(m_sCoursesFilePath, FileMode.Create);
					BinaryFormatter l_oBinFormatter = new BinaryFormatter();

					hl.Core.logger.Write("Saving Downloaded Courses...");
					l_oBinFormatter.Serialize(l_oStream, hl.DataCenter);
					l_oStream.Close();

					hl.Core.logger.WriteLn(" Done");
				}
				catch (Exception l_oException)
				{
					hl.Core.logger.WriteLn("Error Saving Courses - " + l_oException.Message);
				}
			}
		}

		/// <summary>
		/// Loads courses data from a file
		/// </summary>
		public void CoursesLoad()
		{
			// Load the previously saved courses from file
			if (File.Exists(m_sCoursesFilePath))
			{
				FileStream l_oStream = File.Open(m_sCoursesFilePath, FileMode.Open);
				BinaryFormatter l_oBinFormatter = new BinaryFormatter();

				hl.DataCenter = (CDataCenter)l_oBinFormatter.Deserialize(l_oStream);
				l_oStream.Close();

				CoursesLoadedSafe();
			}
		}

		private void FormMain_Load(object sender, System.EventArgs e)
		{

			//frm_About my_frm_about = new frm_About();
			//my_frm_about.ShowDialog(this);
/*
			cmb_Institute.Items.AddRange(
				new TMy_Item_University[] {
				  new TMy_Item_University(	"Tel Aviv University   - virtual.tau.ac.il",
				  TMy_University.TAU),
				  new TMy_Item_University(	"Ben Gurion University   - hl2.bgu.ac.il",
				  TMy_University.BGU),
				  new TMy_Item_University(	"Hebrew University of Jerusalem   - owl.huji.ac.il",
				  TMy_University.HUJI),
				  new TMy_Item_University(	"Bar Ilan University   - hl2.biu.ac.il",
				  TMy_University.BIU),
				  new TMy_Item_University(	"Haifa   - virtualnew.haifa.ac.il",
				  TMy_University.Haifa),
				  new TMy_Item_University(	"The College of Management   - portal.colman.ac.il",
				  TMy_University.Colman),
				  new TMy_Item_University(	"Holon Institute of Technology   - hl.hit.ac.il",
				  TMy_University.HIT),
				  new TMy_Item_University(	"Sapir College   - learn.sapir.ac.il",
				  TMy_University.Sapir),
				  new TMy_Item_University(	"CET [Matah]   - highlearn2002.cet.ac.il",
				  TMy_University.CET),
				  new TMy_Item_University(	"Afeka College    - highlearn.afeka.ac.il",
				  TMy_University.Afeka),
				  new TMy_Item_University(	"Sami Shamoon College - elearn.sce.ac.il",
				  TMy_University.SCE),
			});
			cmb_Institute.SelectedIndex = 0;
*/
			Config_Load();

			comboBoxInstitute.SelectedIndex = 0;
			
			textBoxDownloadsDirectory.Text = m_sDownloadsPath;

			btn_Log.Checked = false;

/*			Version ver = new Version(Application.ProductVersion);
			this.Text += " - Ver: " +
					ver.Major + "." + ver.Minor + "." + ver.Build +
					" Build " + ver.Revision;*/

			edt_Verbose_Level.Enabled = buttonAbort.Enabled;
		}

		private void SetGUIState(EState a_eState)
		{
			switch (a_eState)
			{
				case EState.Disconnected:
					UpdateStatus("מנותק");

					toolStripStatusLabel.ForeColor = Color.Red;

					buttonAbort.Enabled = false;
					buttonStart.Enabled = true;

					textBoxUsername.Enabled = true;
					textBoxPassword.Enabled = true;

					textBoxDownloadsDirectory.Enabled = true;
					buttonBrowse.Enabled = true;

					buttonStartDownloading.Enabled = false;

					break;

				case EState.Connected:
					UpdateStatus("מחובר");

					toolStripStatusLabel.ForeColor = Color.Green;

					buttonAbort.Enabled = true;
					buttonStart.Enabled = false;

					textBoxUsername.Enabled = false;
					textBoxPassword.Enabled = false;

					textBoxDownloadsDirectory.Enabled = true;
					buttonBrowse.Enabled = true;

					buttonStartDownloading.Enabled = true;

					break;

				case EState.Downloading:
					UpdateStatus("מכין קבצים...");
					toolStripStatusLabel.ForeColor = Color.Black;


					buttonAbort.Enabled = true;
					buttonStart.Enabled = false;

					textBoxUsername.Enabled = false;
					textBoxPassword.Enabled = false;

					textBoxDownloadsDirectory.Enabled = false;
					buttonBrowse.Enabled = false;

					buttonStartDownloading.Enabled = false;
					
					break;
			}
		}

		private void buttonStart_Click(object sender, EventArgs e)
		{
			CLogger.LogFunctionEntry();
			Initialize();
			Config_Save_UI();

			hl.CONFIG_USERNAME = textBoxUsername.Text;
			hl.CONFIG_PASSWORD = textBoxPassword.Text;

			m_sCoursesFilePath = m_sConfigurationDirectory + hl.CONFIG_USERNAME + COURSES_FILE_PATH_END;

			// For Testing
			if (DEBUG_COURSE)
			{
				TestingUtilites.SimulateCourseLoading(hl, "דוגמא", "Dump.dump");
				TestingUtilites.SimulateCourseLoading(hl, "1דוגמא", "Dump.dump");
				TestingUtilites.SimulateCourseLoading(hl, "2דוגמא", "Dump.dump");
			}
			else
			{
				hl.Connect(true);

				CoursesLoad();

				hl.GetAvailibleCourses(true);
			}
			
			buttonAbort.Enabled = true;
			buttonStart.Enabled = false;

			edt_Verbose_Level.Enabled = buttonAbort.Enabled;

			// Reset Progress GUI
			//				edt_Progress_Course.Text	= "";
			//				edt_Progress_File.Text		= "";
			//				prg_Courses.Value			= 0;
			//				prg_File.Value				= 0;
		}

		private void buttonAbort_Click(object sender, EventArgs e)
		{
			hl.Disconnect();
		}

		private void listBoxCourses_MouseDoubleClick(object sender, MouseEventArgs e)
		{
			ListViewItem l_oItem;
			if (e.Button == MouseButtons.Left)
			{
				l_oItem = listViewCourses.GetItemAt(e.X, e.Y);
				if (l_oItem.Index > -1)
				{
					hl.GetCourseInformation(hl.DataCenter.Courses[l_oItem.Text].Name, false, true);
				}
			}
		}

		private void listBoxCourses_SelectedIndexChanged(object sender, EventArgs e)
		{
			RefreshCourseDetails();
		}

		private void treeViewFolders_AfterSelect(object sender, TreeViewEventArgs e)
		{
			RefreshFilesDetails();
		}

		private void buttonStartDownloading_Click(object sender, EventArgs e)
		{
			SetGUIState(EState.Downloading);

			foreach (ListViewItem l_oItem in listViewCourses.Items)
			{
				hl.DataCenter.Courses[l_oItem.Text].Download = l_oItem.Checked;
			}

			UpdateDownloadsPath(textBoxDownloadsDirectory.Text);
			hl.DownloadAll(true);
		}

		private void treeViewFolders_AfterCheck(object sender, TreeViewEventArgs e)
		{
			// Prevent running when the tree is populated
			if (!m_bTreeViewPopulating)
			{
				// Get the relevant folder
				FolderItem l_oFolder = hl.DataCenter.Courses[listViewCourses.SelectedItems[0].Text].Data.GetFolder(e.Node.FullPath);

				if ((e.Action == TreeViewAction.ByKeyboard) || (e.Action == TreeViewAction.ByMouse))
				{
					// And set!
					l_oFolder.Download = e.Node.Checked;

					RefreshFoldersCheckedState(l_oFolder, e.Node);
					RefreshFilesDetails();
				}
			}
		}

		private void SetCheckedState(Control a_oControl, Boolean a_bState)
		{
			if (a_oControl == listViewCourses)
			{
				foreach (ListViewItem l_oItem in listViewCourses.Items)
				{
					l_oItem.Checked = a_bState;
				}
			}
			if (a_oControl == checkedListBoxFiles)
			{
				if (m_oCurrentFolder != null)
				{
					m_oCurrentFolder.Download = a_bState;
					RefreshFilesDetails();
				}
			}
			if (a_oControl is TreeView)
			{
				foreach (FolderItem l_oFolder in m_oCurrentCourse.Data.Folders.Values)
				{
					l_oFolder.Download = a_bState;
				}
				foreach (FileItem l_oFile in m_oCurrentCourse.Data.Files.Values)
				{
					l_oFile.Download = a_bState;
				}

				RefreshFoldersCheckedState();
			}
		}

		private void toolStripMenuItemMarkAll_Click(object sender, EventArgs e)
		{
			SetCheckedState(contextMenuStripRight.SourceControl, true);
		}
		private void toolStripMenuItemUnMarkAll_Click(object sender, EventArgs e)
		{
			SetCheckedState(contextMenuStripRight.SourceControl, false);
		}
		private void toolStripMenuItemDownloadCourseInformation_MouseDown(object sender, MouseEventArgs e)
		{
			if (listViewCourses.SelectedItems.Count > 0)
			{
				hl.GetCourseInformation(listViewCourses.SelectedItems[0].Text, true, true);
			}
		}

		private void checkedListBoxFiles_ItemCheck(object sender, ItemCheckEventArgs e)
		{
			if (m_oCurrentFolder != null)
			{
				m_oCurrentFolder.Files[checkedListBoxFiles.Items[e.Index].ToString()].Download = (e.NewValue == CheckState.Checked);
			}
		}

		private void contextMenuStripFolders_Click(object sender, EventArgs e)
		{

		}

		private void אודותToolStripMenuItem_Click(object sender, EventArgs e)
		{
			(new frm_About()).Show();
		}
		private void יציאהToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Application.Exit();
		}

		private void listViewCourses_MouseDown(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
			{
				if (listViewCourses.GetItemAt(e.X, e.Y) != null)
				{
					contextMenuStripCourses.Show(listViewCourses, e.X, e.Y);
				}
			}
		}

		private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
		{
			Config_Save_UI();
		}

		private void button1_Click(object sender, EventArgs e)
		{
			CLogger.LogMessage("Message");
		}

		private void buttonOpenDownloadsDirectory_Click(object sender, EventArgs e)
		{
			System.Diagnostics.Process.Start(m_sDownloadsPath); 
		}

		private void UpdateDownloadsPath(string a_sPath)
		{
			try
			{
				if (!(Directory.Exists(a_sPath)))
				{
					Directory.CreateDirectory(a_sPath);
				}
				FileStream l_oFile = File.Create(a_sPath + "\\Test.dat");
				l_oFile.Close();
				File.Delete(a_sPath + "\\Test.dat");

				m_sDownloadsPath = a_sPath;
			}
			catch (UnauthorizedAccessException e)
			{
				String l_sMessage = "מיקום זה הוא מיקום מוגן" + "\n" + "אם ברצונך לשמור למיקום זה בכל זאת, אנא הרץ את התוכנה שנית עם הרשאות אדמיניסטרציה";
				MessageBox.Show(l_sMessage, "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
			catch (Exception e)
			{
				CLogger.LogMessage("Path is invalid. Failed creating directory. Reverted to the original path");
				throw e;
			}

			textBoxDownloadsDirectory.Text = m_sDownloadsPath;

			if (hl != null)
			{
				hl.SavePath = m_sDownloadsPath;
			}
		}

		private void buttonBrowse_Click(object sender, EventArgs e)
		{
			FolderBrowserDialog l_oDialog = new FolderBrowserDialog();

			l_oDialog.ShowNewFolderButton = true;
			l_oDialog.SelectedPath = textBoxDownloadsDirectory.Text;

			if (l_oDialog.ShowDialog() == DialogResult.OK)
			{
				UpdateDownloadsPath(l_oDialog.SelectedPath);			
			}
		}
	}
}
